跳到主要内容

Redis 常见问题

Redis 为什么这么快?

  • 完全基于内存,绝大部分请求是纯粹的内存操作,非常快速;
  • 数据结构简单,对数据操作也简单;
  • 采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;
  • 采用网络 I/O 多路复用技术,来保证在多连接的时候系统的高吞吐量。当你的某个 socket 可读或者可写的时候,它可以给你一个通知。

怎么保证缓存和数据库数据的一致性?

1、从理论上说,只要我们设置了合理的键的过期时间,我们就能保证缓存和数据库的数据最终是一致的。因为只要缓存数据过期了,就会被删除。随后读的时候,因为缓存里没有,就可以查数据库的数据,然后将数据库查出来的数据写入到缓存中。除了设置过期时间,我们还需要做更多的措施来尽量避免数据库与缓存处于不一致的情况发生。

2、新增、更改、删除数据库操作时同步更新 Redis,可以使用事物机制来保证数据的一致性。

一般有如下四种方案,详情看这里:

  1. 先更新数据库,后更新缓存
  2. 先更新缓存,后更新数据库
  3. 先删除缓存,后更新数据库
  4. 先更新数据库,后删除缓存

第一种和第二种方案,没有人使用的,因为第一种方案存在问题是:并发更新数据库场景下,会将脏数据刷到缓存。 第二种方案存在的问题是:如果先更新缓存成功,但是数据库更新失败,则肯定会造成数据不一致。

目前主要用第三和第四种方案

Redis 内存淘汰策略有哪些?

volatile-lru:从已设置过期时间的数据集(server. db[i]. expires)中挑选最近最少使用的数据淘汰;

volatile-ttl:从已设置过期时间的数据集(server. db[i]. expires)中挑选将要过期的数据淘汰。

volatile-random:从已设置过期时间的数据集(server. db[i]. expires)中任意选择数据淘汰。

allkeys-lru:从数据集(server. db[i]. dict)中挑选最近最少使用的数据淘汰。

allkeys-random:从数据集(server. db[i]. dict)中任意选择数据淘汰。

no-enviction(驱逐):禁止驱逐数据。

connect 与 pconnect 的区别

在 Redis 中,connectpconnect 是用于建立与 Redis 服务器的连接的函数,它们之间有以下区别:

1、connect(短连接):connect 函数用于建立短连接,每次调用都会创建一个新的连接,并在执行完 Redis 命令后立即关闭连接。这意味着每次执行 Redis 命令都需要重新进行连接和认证,适用于临时性的、低频率的 Redis 操作。

2、pconnect(持久连接):pconnect 函数用于建立持久连接,即复用已经建立的连接,连接不会在每次调用后关闭,而是保持长连接状态。这样可以减少每次连接和认证的开销,提高操作的效率。当需要多次执行 Redis 命令时,可以使用 pconnect 函数来保持连接的持久性,适用于高频率的 Redis 操作。

总结:

  • connect 是每次都创建新连接的短连接方式,适用于临时性的低频率操作。
  • pconnect 是复用已建立连接的持久连接方式,适用于高频率的 Redis 操作,能够提高操作效率。

需要注意的是,在使用 pconnect 进行持久连接时,需要谨慎管理连接池和资源,以防止连接资源耗尽或长时间空闲的连接被服务器主动关闭。

Redis 宕机了怎么办?

Redis是如何实现故障自动恢复的?

其除了具有非常高的性能之外,还需要保证高可用,在故障发生时,尽可能地降低故障带来的影响,Redis也提供了完善的故障恢复机制:哨兵。

Redis Sentinel(哨兵)是 Redis 的一个高可用性解决方案,用于监控和管理 Redis 主从复制架构中的故障恢复和故障转移。哨兵是一个独立的进程,可以监控多个 Redis 实例,并在主节点发生故障时自动将一个从节点升级为新的主节点。

哨兵的主要功能包括:

  1. 监控:哨兵定期检查 Redis 主节点和从节点的状态,确保它们正常工作。如果一个节点无法正常响应,哨兵会将其标记为下线状态。

  2. 故障检测和自动故障转移:当一个 Redis 主节点被标记为下线状态时,哨兵会进行故障检测,确认主节点是否真的不可用。如果确认主节点不可用,哨兵会选择一个健康的从节点,并将其升级为新的主节点。

  3. 配置提供和重配置:哨兵会监控 Redis 配置的变化,并在需要时将新的配置传播给 Redis 客户端。这样,客户端可以通过哨兵获取 Redis 服务的最新配置信息。

通过使用哨兵,可以提供 Redis 的高可用性,确保在主节点故障时自动进行故障转移,从而保证 Redis 服务的连续可用性。哨兵还可以自动监控并重新配置 Redis 的主从架构,适应变化的需求。

需要注意的是,Redis Sentinel 是一个独立的组件,需要单独部署和配置,而不是作为 Redis 本身的一部分。

大 key 问题怎么处理?

在 Redis 中一个 key 或是 value 大小最大是 512M,最多容纳 2322^{32} 个key,但是如果你的 key 或是 value 太大,会导致 Redis 单线程处理时间过长,引起 Redis 阻塞,影响 Redis 的性能。

是在 Redis 中存储了大量数据的单个键,这可能会对 Redis 的性能和内存使用产生负面影响。处理 Redis 的大 key 问题可以考虑以下方法:

  1. 分割大 key:将大 key 拆分成多个小的键值对,将数据分散存储在多个键中。例如,可以使用哈希或列表等数据结构将数据分片存储,每个片段对应一个小的键。

  2. 使用分布式存储:将大量数据存储在多个 Redis 节点上,利用 Redis 的集群功能或使用分布式缓存方案,如 Redis Cluster、Redis Sentinel 或第三方的分布式缓存中间件,将数据分散存储在不同的节点上,以降低单个节点的负载。

  3. 数据压缩:对于大型的数据对象,可以考虑使用数据压缩算法,如 GZIP 或 Snappy,将数据进行压缩后存储在 Redis 中。这可以减少内存占用,并且在需要使用数据时进行解压缩。

  4. 使用分页查询:对于大数据集合,可以考虑使用分页查询的方式,将数据划分为多个页,按需加载和处理数据,而不是一次性获取全部数据。

  5. 使用其他存储引擎:如果大 key 问题严重影响 Redis 的性能和稳定性,可以考虑使用其他适合大数据存储的存储引擎,如分布式文件系统、数据库等,将大数据存储在这些系统中,而不是直接存储在 Redis 中。

需要根据具体的应用场景和需求选择合适的处理方法。对于大 key 问题,一般需要结合数据访问模式、数据量大小、系统性能要求等因素进行综合考虑,并根据实际情况选择合适的处理策略。